/***************************************** 
 * Desc: UGUIView Editor Inspector
*****************************************/

using Common.UGUI.Base;
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Common.UserEditor.UGUIViewSpace {

    public struct UGUIViewOnValueCallback {

        public UGUIView[] Target;

        public Action<UGUIView[], string> SetNameCallback;

        public Action<UGUIView[], bool> SetActiveCallback;
    }

    [CustomEditor(typeof(UGUIView))]
    [CanEditMultipleObjects]
    public class UGUIViewInspector : Editor {

        #region 域

        /// <summary>
        /// 是否展示原生的面板
        /// </summary>
        private static bool _ifShowOriginalInspector = false;

        /// <summary>
        /// 通用状态展示Label样式
        /// </summary>
        public static GUIStyle UGUIViewStatusLabel = null;
        /// <summary>
        /// 通用状态展示Toggle样式
        /// </summary>
        public static GUIStyle UGUIViewStatusToggle = null;
        /// <summary>
        /// 通用按钮样式
        /// </summary>
        public static GUIStyle UGUIViewSmallButton = null;

        public static readonly float UITabLength = 50f;

        private static readonly Type _gameObjectType = typeof(GameObject);

        #endregion

        public override void OnInspectorGUI() {

            UnityEngine.Object[] objects = targets;
            int len = objects.Length;
            UGUIView[] uguiViews = new UGUIView[len];
            for (int i = 0; i < len; ++i) {
                uguiViews[i] = (UGUIView)objects[i];
            }

            GUILayout.Space(10);

            ShowUGUIView(uguiViews, base.OnInspectorGUI, new UGUIViewOnValueCallback());
        }

        #region 初始化

        private readonly static int _fontSize = 18;
        private readonly static string _TextColorString = "#4C80D9FF";

        private static void Check2InitGUIStyles() {

            if (UGUIViewStatusLabel == null) {

                UGUIViewStatusLabel = new GUIStyle(GUI.skin.label);

                Color color = Color.black;

                if (ColorUtility.TryParseHtmlString(_TextColorString, out color)) {

                    UGUIViewStatusLabel.normal.textColor = color;
                }
                UGUIViewStatusLabel.fontSize = _fontSize;
                UGUIViewStatusLabel.fontStyle = FontStyle.Normal;
            }

            if (UGUIViewStatusToggle == null) {

                UGUIViewStatusToggle = new GUIStyle(GUI.skin.toggle);

                Color color = Color.black;

                if (ColorUtility.TryParseHtmlString(_TextColorString, out color)) {

                    UGUIViewStatusToggle.normal.textColor = color;
                    UGUIViewStatusToggle.onNormal.textColor = color;
                    UGUIViewStatusToggle.active.textColor = color;
                    UGUIViewStatusToggle.onActive.textColor = color;
                }

                UGUIViewStatusToggle.fontSize = _fontSize;
                UGUIViewStatusToggle.fontStyle = FontStyle.Normal;
            }

            if (UGUIViewSmallButton == null) {

                UGUIViewSmallButton = new GUIStyle(GUI.skin.button);

                Color color = Color.black;

                if (ColorUtility.TryParseHtmlString(_TextColorString, out color)) {

                    UGUIViewSmallButton.normal.textColor = color;
                    UGUIViewSmallButton.onNormal.textColor = color;
                    UGUIViewSmallButton.active.textColor = color;
                    UGUIViewSmallButton.onActive.textColor = color;
                }

                UGUIViewSmallButton.fontSize = _fontSize;
                UGUIViewSmallButton.fontStyle = FontStyle.Bold;
            }

        }

        #endregion

        #region 自定义子面板

        private static void ShowIfShowOriginalInspectorButton(Action originalInspectorFunc) {

            if (_ifShowOriginalInspector) {
                originalInspectorFunc();
            }

            if (_ifShowOriginalInspector) {
                if (GUILayout.Button("HideOriginalData", UGUIViewSmallButton, GUILayout.ExpandWidth(false))){
                    _ifShowOriginalInspector = false;
                }
            } else {
                if (GUILayout.Button("ShowOriginalData", UGUIViewSmallButton, GUILayout.ExpandWidth(false))){
                    _ifShowOriginalInspector = true;
                }
            }
        }

        private static void ShowSaveDataButton(UGUIView[] uguiViews) {

            UGUIView uguiView = uguiViews[0];

            GUILayout.BeginHorizontal();

            GUILayout.Label("保存数据到预制体:", UGUIViewStatusLabel, GUILayout.ExpandWidth(false));

            if(GUILayout.Button("Save", UGUIViewSmallButton, GUILayout.ExpandWidth(false))) {
                
                GameObject prefabRootGo = PrefabUtility.FindPrefabRoot(uguiView.GameObject);

                if (prefabRootGo != null) {

                    UnityEngine.Object prefabRoot = PrefabUtility.GetPrefabParent(prefabRootGo);

                    if (prefabRoot != null) {

                        PrefabUtility.ReplacePrefab(prefabRootGo, prefabRoot, ReplacePrefabOptions.ConnectToPrefab);

                        EditorUtility.SetDirty(prefabRoot);
                        
                        AssetDatabase.SaveAssets();
                    }
                }
            }

            GUILayout.EndHorizontal();
        }

        private static void ShowName(UGUIView[] uguiViews, ref UGUIViewOnValueCallback callbackStruct) {

            UGUIView uguiView = uguiViews[0];

            GUILayout.BeginVertical();

            GUILayout.Label("Name:", UGUIViewStatusLabel, GUILayout.Width(150));

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);
            //uguiView.SetEditorName(UnityEditorHelper.TextFieldText(uguiView.Name));
            uguiView.SetEditorName(GUILayout.TextField(uguiView.Name));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);
            if (GUILayout.Button("SetName", UGUIViewSmallButton, GUILayout.ExpandWidth(false))) {
                if (callbackStruct.SetNameCallback != null) {
                    callbackStruct.SetNameCallback(callbackStruct.Target, uguiView.name);
                } else {
                    foreach (var oneView in uguiViews) {
                        oneView.SetEditorName(uguiView.name);
                    }
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
        }

        private static void ShowIsActive(UGUIView[] uguiViews, ref UGUIViewOnValueCallback callbackStruct) {

            UGUIView uguiView = uguiViews[0];

            GUILayout.BeginHorizontal();
            GUILayout.Label("IsActive:", UGUIViewStatusLabel, GUILayout.ExpandWidth(false)) ;
            bool active = GUILayout.Toggle(uguiView.IsActive, "", UGUIViewStatusToggle);
            if (callbackStruct.SetActiveCallback != null) {
                callbackStruct.SetActiveCallback(callbackStruct.Target, active);
            } else {

                if (uguiView.IsActive != active) {

                    foreach (var oneView in uguiViews) {

                        oneView.SetActive(active);
                    }
                }
            }
            GUILayout.EndHorizontal();
        }

        private static void ShowSortingOrder(UGUIView[] uguiViews) {

            UGUIView uguiView = uguiViews[0];

            GUILayout.BeginVertical();

            GUILayout.Label("Sorting Order:", UGUIViewStatusLabel, GUILayout.Width(150));

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);
            //string sortingOrderText = UnityEditorHelper.TextFieldText(uguiView.SortingOrder.ToString());
            //string inputValue = GUILayout.TextField(sortingOrderText);
            int order = 0;
            try {

                //order = Convert.ToInt32(inputValue);

            } catch (FormatException e) {

                Debug.LogError("UGUIView sorting order erorr: " + e.Message);

                order = 0;
            }

            foreach (var oneView in uguiViews) {
                oneView.SortingOrder = order;
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);
            if (GUILayout.Button("RefreshByOrderNow", UGUIViewSmallButton, GUILayout.ExpandWidth(false))) {
                uguiView.SortGameObjectBySortingOrder();
            }
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
        }

        private static readonly float _ObjectInputFieldLength = 300f;
        private static void ShowParent(UGUIView[] uguiViews) {

            UGUIView uguiView = uguiViews[0];

            GUILayout.BeginVertical();

            GUILayout.Label("Parent:", UGUIViewStatusLabel, GUILayout.ExpandWidth(false));

            GameObject parentGameObject = null;

            if (uguiView.Parent == null) {

                GUILayout.BeginHorizontal();
                GUILayout.Space(UITabLength);
                GUILayout.Label("Now: null", UGUIViewStatusLabel, GUILayout.ExpandWidth(false));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Space(UITabLength);
                parentGameObject = EditorGUILayout.ObjectField(null, _gameObjectType, true, GUILayout.Width(_ObjectInputFieldLength)) as GameObject;
                GUILayout.EndHorizontal();

            } else {

                GUILayout.BeginHorizontal();
                GUILayout.Space(UITabLength);
                GUILayout.Label("Now: " + uguiView.Parent.Name, UGUIViewStatusLabel, GUILayout.ExpandWidth(false));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Space(UITabLength);
                parentGameObject = EditorGUILayout.ObjectField(uguiView.Parent, _gameObjectType, true, GUILayout.Width(_ObjectInputFieldLength)) as GameObject;
                GUILayout.EndHorizontal();
            }

            if (parentGameObject != null) {

                if (parentGameObject != uguiView.GameObject) {

                    if (uguiView.Parent == null || parentGameObject != uguiView.Parent.GameObject) {

                        if (parentGameObject.GetComponent<UGUIView>() != null) {

                            foreach (var oneView in uguiViews) {
                                oneView.SetParent(parentGameObject.GetComponent<UGUIView>());
                            }
                        } else {

                            Debug.LogError("Must attach an UGUIView gameobject as parent.");
                        }
                    }
                } else {

                    Debug.LogError("Can't  attach self gameobject as an UGUIView parent.");
                }
            } else {

                foreach (var oneView in uguiViews) {
                    oneView.AutoFindParent();
                }
            }

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);
            if (GUILayout.Button("Clear Parent", UGUIViewSmallButton, GUILayout.ExpandWidth(false))) {
                foreach (var oneView in uguiViews) {
                    oneView.SetParent(null);
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
        }

        private static readonly float _ChildrenNameFieldLength = 300f;
        private static void ShowChildren(UGUIView[] uguiViews) {

            GUILayout.BeginVertical();

            GUILayout.Label("Children:", UGUIViewStatusLabel, GUILayout.ExpandWidth(false));

            GUILayout.BeginHorizontal();
            GUILayout.Space(UITabLength);

            if (uguiViews.Length > 1) {

                GUILayout.Label("Only select one GameObject can show it's children.", UGUIViewStatusLabel, GUILayout.ExpandWidth(false));
            } else {

                UGUIView uguiView = uguiViews[0];
                HashSet<UGUIView> childrenSet = uguiView.Children;
                int length = childrenSet.Count;
                if (length > 0) {
                    string[] children = new string[length + 1];
                    UGUIView[] childrenView = new UGUIView[length];
                    int i = 1;
                    foreach (UGUIView view in childrenSet) {
                        children[i] = view.Name;
                        childrenView[i - 1] = view;
                        ++i;
                    }
                    children[0] = "Default";
                    int selected = EditorGUILayout.Popup(0, children, GUILayout.Width(_ChildrenNameFieldLength));
                    if (selected != 0) {

                        int currentSelect = selected - 1;

                        UGUIView selectedView = childrenView[currentSelect];

                        EventSystem es = EventSystem.current;

                        GameObject selectedGO = selectedView.GameObject;

                        Selection.SetActiveObjectWithContext(selectedGO, null);
                    }
                } else {
                    EditorGUILayout.Popup(0, new string[] { "None" }, GUILayout.Width(_ChildrenNameFieldLength));
                } 
            }

            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }

        #endregion

        #region 通用自定义面板接口

        public static void ShowUGUIView(UGUIView[] uguiViews, Action originalInspectorFunc, UGUIViewOnValueCallback callbacks) {

            //uguiView.AutoFindParent(true);

            Check2InitGUIStyles();

            GUILayout.BeginVertical();

          //  GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowIfShowOriginalInspectorButton(originalInspectorFunc);

         //   GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowSaveDataButton(uguiViews);

         //   GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowName(uguiViews, ref callbacks);

         //   GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowSortingOrder(uguiViews);

          //  GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowParent(uguiViews);

          //  GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowChildren(uguiViews);

           // GUILayout.Space(UnityEditorCommonConfig.GUILayoutGapSpace);

            ShowIsActive(uguiViews, ref callbacks);

            GUILayout.EndVertical();
        }

        #endregion
    }
}
